#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/execution_monitor.hpp>
#include "bmock.hpp"
#include "bmock_control_tools_mock.hpp"

static void f()
{
	STATIC_MOCK_VOID(0, ());
}

static void g() {
	MOCK_VOID(0,());
}
static int k() {
	MOCK(0,());
	return 1;
}

static void h()
{
	g();
}

static void h1() {
}
static int h2() {
	return 0;
}



struct repetition_tester22{
	repetition_tester22() {
		BMOCK_CREATE_MOCK(*);
	}
	int result;
};

BOOST_AUTO_TEST_CASE(use_static_and_dynamic_DynamicGenerated) {
	int result;

	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c, f());
	__BMOCK_EXPECT_RETURN_C(c, 2, k());
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(f());
	BOOST_CHECK_NO_THROW(result = k());
	BOOST_CHECK_EQUAL(result, 2);
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(use_static_and_dynamic_DynamicNotGenerated) {
	int result;

	__BMOCK_CONTROL(c);	
	__BMOCK_EXPECT_C(c, f());	
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(f());
	result = k();
	BOOST_CHECK_EQUAL(result, 1);
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ReplayWithoutExpect22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		BOOST_CHECK_NO_THROW(__BMOCK_REPLAY_C(c1));
		BOOST_CHECK_NO_THROW(__BMOCK_VERIFY_C(c1));
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_DuplicateReplay22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+8);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(bmock::message(bmock::INVALID_REPLAY),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(__BMOCK_REPLAY_C(c1),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_MisplacedVerify22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+7);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(bmock::message(bmock::INVALID_VERIFY),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		BOOST_CHECK_THROW(__BMOCK_VERIFY_C(c1),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_NotReceived22) {
	const char *msg = "Function call 'f' has not been received (expected: 1, actual: 0)";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg,loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(__BMOCK_VERIFY_C(c1),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_Received22) {
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,f());
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(f());
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_Wrong22) {
	const std::string msg = "BMOCK_EXPECT_STR(g,\"test_static_dynamic_mocks_combined.cpp\",13,0,());";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_THROW_C(c,new boost::execution_aborted(),t->error(msg,loc,true));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_THROW(g(),boost::execution_aborted);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_MissingReplay22) {
	const std::string msg = "BMOCK_EXPECT_STR(f,\"test_static_dynamic_mocks_combined.cpp\",9,0,());";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg+"(m.b. BMOCK_REPLAY is missing)",loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		BOOST_CHECK_THROW(f(),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}


BOOST_AUTO_TEST_CASE(testFunctionCall_Unexpected22) {
	const std::string msg = "BMOCK_EXPECT_STR(f,\"test_static_dynamic_mocks_combined.cpp\",9,0,());";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+7);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg,loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		BOOST_CHECK_THROW(f(),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ReplayAfterVerify22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+10);

	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		__BMOCK_VERIFY_C(c1);
		BOOST_CHECK_NO_THROW(__BMOCK_REPLAY_C(c1));
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ReplayAfterCheck22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+9);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(bmock::message(bmock::INVALID_REPLAY),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		BOOST_CHECK_THROW(__BMOCK_REPLAY_C(c1),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_DuplicateVerify22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+10);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(bmock::message(bmock::INVALID_VERIFY),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		__BMOCK_VERIFY_C(c1);
		BOOST_CHECK_THROW(__BMOCK_VERIFY_C(c1),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ExpectAfterVerify22) {
	__BMOCK_CONTROL(c);
	__BMOCK_CREATE_MOCK_C((&c),*);
	__BMOCK_EXPECT_C(c,f());
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(f());
	__BMOCK_VERIFY_C(c);
	__BMOCK_EXPECT_C(c,f());
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_NO_THROW(f());
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_CheckAfterVerify22) {
	const std::string msg = "BMOCK_EXPECT_STR(f,\"test_static_dynamic_mocks_combined.cpp\",9,0,());";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+10);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg+"(m.b. BMOCK_REPLAY is missing)",loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		__BMOCK_VERIFY_C(c1);
		BOOST_CHECK_THROW(f(),bmock::location);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_UnexpectedDestructor_Verify22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::INVALID_TERMINATE),bmock::location(__FILE__,__LINE__+6)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_UnexpectedDestructor_Check22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::INVALID_TERMINATE),bmock::location(__FILE__,__LINE__+7)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		__BMOCK_REPLAY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_UnexpectedDestructor_Replay22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::INVALID_TERMINATE),bmock::location(__FILE__,__LINE__+5)));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ExpectForNonMock_void22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::EXPECT_FOR_NON_MOCK),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_EXPECT_C(c1,h1());
		__BMOCK_REPLAY_C(c1);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ExpectForNonMock_int22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::EXPECT_FOR_NON_MOCK),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_EXPECT_RETURN_C(c1,1,h2());
		__BMOCK_REPLAY_C(c1);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BOOST_AUTO_TEST_CASE(testFunctionCall_ExpectForNonMock_exception22) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_C(c,t->error(bmock::message(bmock::EXPECT_FOR_NON_MOCK),loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);
		__BMOCK_EXPECT_THROW_C(c1,new bmock::location(),h2());
		__BMOCK_REPLAY_C(c1);
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}
BOOST_AUTO_TEST_CASE(test_mock_call_without_expect_before_replay22) {
	const std::string msg = "BMOCK_EXPECT_STR(g,\"test_static_dynamic_mocks_combined.cpp\",13,0,());";
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+6);

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg+"(m.b. BMOCK_REPLAY is missing)",loc));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_C(c1,f());
		BOOST_CHECK_THROW(h(),bmock::location);
		__BMOCK_REPLAY_C(c1);
		BOOST_CHECK_NO_THROW(f());
		__BMOCK_VERIFY_C(c1);
	}
	__BMOCK_VERIFY_C(c);
}

BMOCK_TEST(repetition_tester22,testVoidFunctionCall_Repetition22) {
	BMOCK_EXPECT(f());
	BMOCK_REPEAT(5);
	BMOCK_REPLAY;
	for(int i=0;i<5;i++)
		BOOST_CHECK_NO_THROW(f());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22,testFunctionCall_Repetition2) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT(5);
	BMOCK_REPLAY;
	for(int i=0;i<5;i++)
		BOOST_CHECK_NO_THROW(k());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_same_as_max) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT_RANGE(1,5);
	BMOCK_REPLAY;
	for(int i=0;i<5;i++)
		BOOST_CHECK_NO_THROW(k());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_same_as_min) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT_RANGE(1,5);
	BMOCK_REPLAY;
	for(int i=0;i<1;i++)
		BOOST_CHECK_NO_THROW(k());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_between_max_and_min) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT_RANGE(1,5);
	BMOCK_EXPECT(f());
	BMOCK_REPLAY;
	for(int i=0;i<3;i++)
		BOOST_CHECK_NO_THROW(k());
	BOOST_CHECK_NO_THROW(f());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_between_max_and_min_infinite_max) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT_RANGE(1,BMOCK_INFINITE);
	BMOCK_EXPECT(f());
	BMOCK_REPLAY;
	for(int i=0;i<3;i++)
		BOOST_CHECK_NO_THROW(k());
	BOOST_CHECK_NO_THROW(f());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_max_infinite) {
	BMOCK_EXPECT_RETURN(result,k());
	BMOCK_REPEAT_RANGE(3,BMOCK_INFINITE);
	BMOCK_EXPECT(f());
	BMOCK_REPLAY;
	for(int i=0;i < 100;i++)
		BOOST_CHECK_NO_THROW(k());
	BOOST_CHECK_NO_THROW(f());
	BMOCK_VERIFY;
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_called_more_than_max) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
	const bmock::location          loc(__FILE__,__LINE__+9);
	const std::string msg = "BMOCK_EXPECT_RETURN_STR(int,k,\"test_static_dynamic_mocks_combined.cpp\",16,0,());";

	__BMOCK_EXPECT_THROW_C(c,new boost::execution_aborted(),t->error(msg,loc,true));
	__BMOCK_REPLAY_C(c);
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_RETURN_C(c1, result, k());
		__BMOCK_REPEAT_RANGE_C(c1, 1, 5);
		__BMOCK_REPLAY_C(c1);
		{
			for(int i=0;i<5;i++)
				BOOST_CHECK_NO_THROW(k());
			BOOST_CHECK_THROW(k(),boost::execution_aborted);
		}
	}
	__BMOCK_VERIFY_C(c);
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_called_less_than_min) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
#ifndef __clang__
	const bmock::location          loc(__FILE__,__LINE__+18);
#else
	const bmock::location          loc(__FILE__,__LINE__+9);
#endif
	const char *msg = "Function call 'k' has not been received (expected: 3, actual: 2)";

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg,loc));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_THROW( 
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_RETURN_C(c1,result,k());
		__BMOCK_REPEAT_RANGE_C(c1, 3, 5);
		__BMOCK_REPLAY_C(c1);
		for(int i=0;i<2;i++)
			BOOST_CHECK_NO_THROW(k());		
		__BMOCK_VERIFY_C(c1);
	}	
	,bmock::location);
	__BMOCK_VERIFY_C(c);
}

BMOCK_TEST(repetition_tester22, testFunctionCall_Repetition_range_called_less_than_min_infinite_max) {
	__BMOCK_CONTROL(c);
	const bmock::control_tools_ptr t(new bmock::control_tools_mock(c));
#ifndef __clang__
	const bmock::location          loc(__FILE__,__LINE__+18);
#else
	const bmock::location          loc(__FILE__,__LINE__+9);
#endif
	const char *msg = "Function call 'k' has not been received (expected: 3, actual: 1)";

	__BMOCK_EXPECT_THROW_C(c,new bmock::location(loc),t->error(msg,loc));
	__BMOCK_REPLAY_C(c);
	BOOST_CHECK_THROW( 
	{
		bmock::test_mode_control c1(bmock::location(__FILE__,__LINE__),t);__BMOCK_CREATE_MOCK_C((&c1),*);
		__BMOCK_EXPECT_RETURN_C(c1,result,k());
		__BMOCK_REPEAT_RANGE_C(c1, 3, BMOCK_INFINITE);
		__BMOCK_REPLAY_C(c1);
		for(int i=0;i<1;i++)
			BOOST_CHECK_NO_THROW(k());		
		__BMOCK_VERIFY_C(c1);
	}	
	,bmock::location);
	__BMOCK_VERIFY_C(c);
}
